﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aribaccio;
using Aribaccio.Core;
using BDPAutodetect.Device;
using BDPAutodetect.Models;
using CommunityToolkit.Mvvm.ComponentModel;

namespace BDPAutodetect.Mgrcore
{
    /// <summary>
    /// 工位检测任务
    /// </summary>
    public partial class DetectJobStation : DetectJobBase
    {
        /// <summary>
        /// 是否第一次执行
        /// </summary>
        protected bool IsFirstExecute { get; set; }
        /// <summary>
        /// 检测任务线程
        /// </summary>
        protected PeriodicTaskManual MonitorTask { get; set; }
        /// <summary>
        /// 检测输入输出任务
        /// </summary>
        protected DetectJobSensorSign DetectJobSensor { get; set; }
        /// <summary>
        /// 检测客户机端任务
        /// </summary>
        protected DetectJobCustomer DetectJobCustomer { get; set; }
        /// <summary>
        /// 检测记录管理实例
        /// </summary>
        protected DetectRecordManager? DetectRecordMgr { get; set; }
        /// <summary>
        /// 检测指标数据队列
        /// </summary>
        protected ConcurrentQueue<MTargetDetectDto> TargetDataQueue { get; set; }
        /// <summary>
        /// 当前检测指标数据
        /// </summary>
        protected MTargetDetectDto? TargetData { get; set; }
        /// <summary>
        /// 工位检测传输数据
        /// </summary>
        [ObservableProperty]
        protected MStationDetectDto detectData;

        /// <summary>
        /// 是否启动
        /// </summary>
        public bool IsStartup => this.DetectStatus == DetectJobStatus.Startup || this.DetectStatus == DetectJobStatus.StartDetect;
        /// <summary>
        /// 是否可以启动
        /// </summary>
        public bool IsCanStartup => this.DetectStatus == DetectJobStatus.None || this.DetectStatus == DetectJobStatus.Finish;

        /// <summary>
        /// 构造函数
        /// </summary>
        public DetectJobStation(DeviceStationType argStationType, MStationDetectDto argDetectData)
            : base(argStationType, $"{argStationType.ToInt()}号工位检测任务", 10, true, false, false)
        {
            this.IsFirstExecute = true;
            this.DetectData = argDetectData;
            this.TargetDataQueue = new ConcurrentQueue<MTargetDetectDto>();
            this.DetectJobSensor = new DetectJobSensorSign(argStationType);
            this.DetectJobCustomer = new DetectJobCustomer(argStationType);
            //从容器中获取-检测记录管理实例
            this.DetectRecordMgr = ContainerManager.Instance.GetContainerServiceRequired<DetectRecordManager>();
            //监测任务线程
            this.MonitorTask = new PeriodicTaskManual($"{argStationType.ToInt()}号工位实时监视任务", 100, MonitorTaskAction, true, true);
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public void Initialize()
        {
            //复位Led和蜂鸣器
            this.DetectJobSensor.ResetSensor();
        }

        /// <summary>
        /// 停止任务线程
        /// </summary>
        public override Result Stop()
        {
            this.MonitorTask.Stop();
            return base.Stop();
        }

        /// <summary>
        /// 启动检测
        /// </summary>
        public override async Task<bool> StartDetect()
        {
            if (!this.IsCanStartup) return true;
            var beResult = await base.StartDetect();
            if (!beResult) return false;

            return await Task.Run(() =>
            {
                this.ResetDetect();
                this.DetectData.SetTargetParameterLimit();
                foreach (var item in this.DetectData.TargetDatas)
                {
                    this.TargetDataQueue.Enqueue(item);
                }
                this.SetDetectStatus(DetectJobStatus.Startup);
                //检查扫码枪是否启用
                if (!this.DetectData.BarcodeEnable)
                {
                    this.SetDetectStart();
                }
                return true;
            });
        }

        /// <summary>
        /// 停止检测
        /// </summary>
        public override async Task StopDetect()
        {
            if (this.IsCanStartup) return;
            await base.StopDetect();
            await this.DetectJobCustomer.StopDetect();
            this.FinishDetect();
        }

        /// <summary>
        /// 暂停检测
        /// </summary>
        public override async Task PauseDetect()
        {
            if (this.DetectStatus != DetectJobStatus.Startup && this.DetectStatus != DetectJobStatus.StartDetect) return;
            //子线程，客户机端停止
            await this.DetectJobCustomer.StopDetect();
            //主线程设置停止
            this.LastDetectStatus = this.DetectStatus;
            this.SetDetectStatus(DetectJobStatus.Pause);
            await base.PauseDetect();
        }

        /// <summary>
        /// 继续检测
        /// </summary>
        public override async Task ContinueDetect()
        {
            if (this.DetectStatus != DetectJobStatus.Pause) return;
            this.SetDetectStatus(this.LastDetectStatus);
            await this.DetectJobCustomer.ContinueDetect();
            await base.ContinueDetect();
        }

        /// <summary>
        /// 结束检测
        /// </summary>
        /// <param name="argResultStatus">检测结果状态</param>
        public override void FinishDetect()
        {
            DetectResultStatus resultStatus = this.DetectData.DetectResultStatus;
            //判断是否全部检测完成，并且有检测结果
            if (resultStatus != DetectResultStatus.None)
            {
                this.DetectData.IncreaseTotalData();
                //存储检测数据
                this.DetectRecordMgr?.SaveData(this.DetectData.CloneDeep());
            }
            this.TargetData = null;
            this.IsFirstExecute = true;
            this.SetDetectStatus(DetectJobStatus.Finish);
            this.SetDetectHummerLightStatus(resultStatus);
            base.FinishDetect();
        }

        /// <summary>
        /// 重置清除数据
        /// </summary>
        public override void ResetDetect()
        {
            this.IsFirstExecute = true;
            this.TargetData = null;
            this.TargetDataQueue.Clear();
            this.DetectData.Reset();
            this.DetectJobCustomer.ResetDetect();
            base.ResetDetect();
        }

        /// <summary>
        /// 检测条码是否存在
        /// </summary>
        /// <param name="argBarcode">条码</param>
        /// <returns></returns>
        public bool IsExistsBarcode(string argBarcode)
        {
            if (DetectData == null) return false;
            if (string.IsNullOrEmpty(argBarcode)) return true;
            if (string.IsNullOrEmpty(DetectData.Barcode)) return false;
            return DetectData.Barcode.Equals(argBarcode, StringComparison.OrdinalIgnoreCase);
        }

        /// <summary>
        /// 清空检测时长
        /// </summary>
        public async Task CleanTime()
        {
            await Task.Run(() =>
            {
                this.DetectData.TotalData.DetectDuration = 0;
                this.DetectRecordMgr?.SaveData(this.DetectData.CloneDeepTotal());
            });
        }

        /// <summary>
        /// 清空检测次数
        /// </summary>
        public async Task CleanNumber()
        {
            await Task.Run(() =>
            {
                this.DetectData.TotalData.DetectCount = 0;
                this.DetectRecordMgr?.SaveData(this.DetectData.CloneDeepTotal());
            });
        }

        /// <summary>
        /// 设置蜂鸣灯关闭
        /// </summary>
        public async Task SetHummerLightOff()
        {
            await Task.Run(() =>
            {
                this.DetectJobSensor.SetHummer(SwitchType.Off);
            });
        }

        /// <summary>
        /// 设置条码，并开始检测
        /// </summary>
        public void SetBarcode(string argBarcode)
        {
            if (this.DetectStatus != DetectJobStatus.Startup) return;
            this.DetectData.Barcode = argBarcode;
            this.SetDetectStart();
        }

        /// <summary>
        /// 手动点击设定条码，检测并开始检测
        /// </summary>
        public void SetBarcodeManual()
        {
            if (this.DetectStatus != DetectJobStatus.Startup) return;
            if (string.IsNullOrWhiteSpace(this.DetectData.Barcode))
            {
                this.DetectData.DetectMsg = "手动设定，必须输入条码";
                return;
            }
            this.SetDetectStart();
        }

        /// <summary>
        /// 设置检查开始
        /// </summary>
        protected void SetDetectStart()
        {
            this.SetDetectStatus(DetectJobStatus.StartDetect);
            //主线程
            base.Active();
        }

        /// <summary>
        /// 设置检测状态
        /// </summary>
        /// <param name="argDetectStatus">检测状态</param>
        protected override void SetDetectStatus(DetectJobStatus argDetectStatus)
        {
            base.SetDetectStatus(argDetectStatus);
            this.DetectData.DetectStatus = argDetectStatus;
            //再设置信号颜色
            switch (this.DetectStatus)
            {
                case DetectJobStatus.Startup:
                    this.DetectData.StartDateTime = DateTime.Now;
                    this.SetDetectHummerLightStatus(LedLightType.Yellow);
                    break;
                case DetectJobStatus.StartDetect:
                case DetectJobStatus.Pause:
                    this.SetDetectHummerLightStatus(LedLightType.Yellow);
                    break;
                case DetectJobStatus.Error:
                    this.SetDetectHummerLightStatus(LedLightType.Red);
                    break;
                case DetectJobStatus.None:
                    this.SetDetectHummerLightStatus(LedLightType.None);
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="argResultStatus"></param>
        protected void SetDetectHummerLightStatus(DetectResultStatus argResultStatus)
        {
            switch (argResultStatus)
            {
                case DetectResultStatus.None: this.SetDetectHummerLightStatus(LedLightType.None); break;
                case DetectResultStatus.Pass: this.SetDetectHummerLightStatus(LedLightType.Green); break;
                case DetectResultStatus.Fail: this.SetDetectHummerLightStatus(LedLightType.Red); break;
            }
        }

        /// <summary>
        /// 设置检测结果蜂鸣灯状态
        /// </summary>
        protected void SetDetectHummerLightStatus(LedLightType argLightType)
        {
            switch (argLightType)
            {
                case LedLightType.None:
                    this.DetectData.SignalColor = Color.Gray;
                    this.DetectJobSensor.ResetSensor();
                    break;
                case LedLightType.Red:
                    this.DetectData.SignalColor = Color.Red;
                    this.DetectJobSensor.SetLedLightOn(argLightType);
                    this.DetectJobSensor.SetHummer(SwitchType.On);
                    break;
                case LedLightType.Green:
                    this.DetectData.SignalColor = Color.Chartreuse;
                    this.DetectJobSensor.SetLedLightOn(argLightType);
                    break;
                case LedLightType.Yellow:
                    this.DetectData.SignalColor = this.DetectStatus == DetectJobStatus.Pause ? Color.GreenYellow : Color.Yellow;
                    this.DetectJobSensor.SetLedLightOn(argLightType);
                    if (this.DetectStatus == DetectJobStatus.Startup)
                    {
                        this.DetectJobSensor.SetHummer(SwitchType.Off);
                    }
                    break;
            }
        }

        /// <summary>
        /// 启动前检查
        /// </summary>
        /// <returns></returns>
        protected override bool CheckStartPre()
        {
            if (!base.CheckStartPre()) return false;
            if (this.DetectData.ParameterData == null)
            {
                this.DetectData.DetectMsg = "检测参数不能为空！";
                return false;
            }
            if (this.DetectData.ParameterData.Limits == null || this.DetectData.ParameterData.Limits.Count <= 0)
            {
                this.DetectData.DetectMsg = "检测参数界限不能为空！";
                return false;
            }
            return true;
        }


        /// <summary>
        /// 执行线程任务
        /// </summary>
        protected void MonitorTaskAction()
        {
            //检测更新接收时间
            if (this.DetectStatus != DetectJobStatus.None && this.DetectStatus != DetectJobStatus.Finish)
            {
                this.DetectData.FinishDateTime = DateTime.Now;
            }
            //检测是否可以启动
            if (!this.IsCanStartup) return;
            //监控信号
            if (this.DetectJobSensor.SwitchStatus)
            {
                _ = this.StartDetect();
            }
        }

        /// <summary>
        /// 执行线程任务
        /// </summary>
        protected override void ExecuteTaskAction()
        {
            if (this.DetectStatus == DetectJobStatus.None
                || this.DetectStatus == DetectJobStatus.Startup
                || this.DetectStatus == DetectJobStatus.Pause)
            {
                return;
            }
            //需要检测是否执行完成
            if (this.DetectData.IsDetectFinish)
            {
                this.FinishDetect();
                return;
            }
            //检测是否非第一次，并等待子线程
            if (!this.IsFirstExecute)
            {
                //所有子线程阻塞等待事件
                this.DetectJobCustomer.ResetEventWaitMain.WaitOne();
                if (this.DetectStatus == DetectJobStatus.Pause)
                {
                    this.DetectJobCustomer.ActiveMain();
                    return;
                }
            }
            this.ExecuteDetectAction();
        }

        /// <summary>
        /// 执行检测任务
        /// </summary>
        protected void ExecuteDetectAction()
        {
            //检测异常后续是否停止结束
            if (this.TargetData != null && this.DetectJobCustomer.DetectStatus == DetectJobStatus.Error)
            {
                while (this.TargetDataQueue.TryDequeue(out MTargetDetectDto? mTargetDetectDto))
                {
                    mTargetDetectDto.SetDetectResultStatus(string.Empty, string.Empty, ReceiveStatus.NG);
                    mTargetDetectDto.DetectStatus = DetectJobStatus.Finish;
                }
                this.TargetData.DetectStatus = DetectJobStatus.Finish;
                return;
            }
            if (this.TargetData == null || this.TargetData.DetectStatus == DetectJobStatus.Finish)
            {
                if (this.TargetDataQueue.TryDequeue(out MTargetDetectDto? mTargetDetectDto))
                {
                    this.TargetData = mTargetDetectDto;
                }
            }
            this.IsFirstExecute = false;
            //设置检测指标
            this.DetectJobCustomer.InitData(this.TargetData);
            //激活子线程
            this.DetectJobCustomer.Active();
        }
    }
}
